package com.lonwin.mes2u8.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lonwin.mes2u8.common.CommonValue;
import com.lonwin.mes2u8.common.MesConfig;
import com.lonwin.mes2u8.common.YonYouConfig;
import com.lonwin.mes2u8.domain.mes.MesCommonResult;
import com.lonwin.mes2u8.domain.mes.MesInventoryQueryParam;
import com.lonwin.mes2u8.domain.mes.MesInventoryQueryResult;
import com.lonwin.mes2u8.domain.u8.*;
import com.lonwin.mes2u8.util.BaseInfoU8;
import com.lonwin.mes2u8.util.MyHttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import openapi4j.exception.OpenAPIException;
import openapi4j.service.InventoryService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 存货操作相关
 *
 * @author DELL
 * @Date 2023-12-14 17:09
 */
@Service
@Slf4j
public class InventoryAppService {

    @Resource
    private MesConfig mesConfig;

    @Resource
    private YonYouConfig yonYouConfig;

    @Resource
    private MesTokenService tokenService;

    /**
     * 从mes系统中获取存货信息
     *
     * @param inventoryId 存货编码
     * @return 存货信息
     */
    public MesInventoryQueryResult queryInventoryFromMes(String inventoryId) {

        String resultString = MyHttpClientUtil.sendPostRequest(
                mesConfig.getAddress() + mesConfig.getInventoryUrl(),
                tokenService.buildTokenHeader(),
                JSONObject.toJSONString(MesInventoryQueryParam.builder().productIdentification(inventoryId).build()),
                MyHttpClientUtil::handleJsonResponse
        );

        MesCommonResult<MesInventoryQueryResult> result = JSONObject.parseObject(
                resultString, new TypeReference<MesCommonResult<MesInventoryQueryResult>>() {}.getType());


        if (Objects.nonNull(result) && result.isSuccess()) {
            log.info("InventoryAppService queryInventoryByMes : inventory query success from mes");
            return JSONObject.parseObject(JSON.toJSONString(result.getResult()), MesInventoryQueryResult.class);
        }
        log.error("InventoryAppService queryInventoryByMes : interface return null");
        return null;
    }

    /**
     * 使用存货id查询U8存货服务
     * @param inventoryId 存货id
     * @return 查询结果，未找到返回null
     */
    public U8InventoryQueryResult queryInventoryFromU8ById(String inventoryId){

        InventoryService inventoryService = new InventoryService();
        JSONObject inventoryResp = null;
        try {
            inventoryResp = inventoryService.get(inventoryId, yonYouConfig.getToAccount());
        } catch (OpenAPIException e) {
            log.error("InventoryAppService.InventoryAppService SDK occur exception : {}", e.getMessage() );
            return null;
        }
        U8InventoryQueryResult result = JSONObject.parseObject(JSONObject.toJSONString(inventoryResp), U8InventoryQueryResult.class);
        log.info("InventoryAppService.InventoryAppService compile : {}", result);

        return Objects.nonNull(result) && CommonValue.U8_RESPONSE_SUCCESS.equals(result.getErrcode()) ? result : null;
    }

    /**
     * 使用存货名查询U8存货服务
     * @param inventoryName 存货名称
     * @return 符合条件的存货列表，没有则返回空数组
     */
    public List<U8InventoryBatchQueryResultInfo> queryInventoryFromU8ByName(String inventoryName) {
        InventoryService inventoryService = new InventoryService();

        U8InventoryBatchQueryParam batchQueryParam = U8InventoryBatchQueryParam.builder()
                .from_account(yonYouConfig.getFromAccount())
                .to_account(yonYouConfig.getToAccount())
                .app_key(yonYouConfig.getAppKey())
                .token(BaseInfoU8.getToken())
                .name(inventoryName.trim())
                .build();

        JSONObject inventoryResp = null;
        try {
            inventoryResp = inventoryService.batchGet(JSONObject.parseObject(JSONObject.toJSONString(batchQueryParam), new TypeReference<HashMap<String, String>>() {}.getType()));
        } catch (OpenAPIException e) {
            log.error("InventoryAppService.queryInventoryFromU8ByName occur exception by SDK : {}", e.getMessage());
            return null;
        }

        U8InventoryBatchQueryResult result = JSONObject.parseObject(JSONObject.toJSONString(inventoryResp), U8InventoryBatchQueryResult.class);
        return Objects.nonNull(result) && CommonValue.U8_RESPONSE_SUCCESS.equals(result.getErrcode()) ? result.getInventory() : Lists.newArrayList();
    }

    /**
     * 使用id判断存货是否不存在于u8系统中
     *
     * @param inventoryId 存货编码
     * @return 判断结果，存在为false
     */
    public boolean isNotExistInventoryU8ById(String inventoryId) {
        return Objects.isNull(queryInventoryFromU8ById(inventoryId));
    }

    /**
     * 使用存货名判断存货是否不存在于u8系统中
     * @param inventoryName 存货名称
     * @return 判断结果，存在为false
     */
    public boolean isNotExistInventoryU8ByName(String inventoryName) {
        return Objects.isNull(queryInventoryFromU8ByName(inventoryName)) || queryInventoryFromU8ByName(inventoryName).isEmpty();
    }

    /**
     * 向u8中新增存货
     *
     * @param u8InventoryAddParam 存货新增参数
     * @return 新增成功对象
     */
    public U8CommonSyncResponse addInventoryOfU8(U8InventoryAddParam u8InventoryAddParam) {

        InventoryService inventoryService = new InventoryService();
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("inventory", u8InventoryAddParam);
        JSONObject addResult = null;
        try {
            addResult = inventoryService.add(JSONObject.toJSONString(paramMap), yonYouConfig.getToAccount(), BaseInfoU8.getTradeId());
        } catch (OpenAPIException e) {
            log.error("InventoryAppService addInventoryOfU8 error 1 : add [{}] by u8 openapi error", u8InventoryAddParam.getCode());
        }

        U8CommonSyncResponse res = null;
        if (Objects.nonNull(addResult)) {
            // TODO 被调接口为异步，返回一个3秒后查看链接的信息，需要做处理
            log.info("InventoryAppService addInventoryOfU8 success 1");
            res = JSONObject.parseObject(JSON.toJSONString(addResult), U8CommonSyncResponse.class);
            return res;
        }

        log.error("InventoryAppService addInventoryOfU8 error 2 : parse u8 openapi response error");
        return null;
    }

    public U8CommonSyncResponse addInventoryOfU8IfNotExist(String inventoryId) {
        boolean notExistInventoryU8ById = isNotExistInventoryU8ById(inventoryId.replace("-", ""));

        if(!notExistInventoryU8ById) {
            log.info("InventoryAppService addInventoryOfU8IfNotExist  [{}] is exist", inventoryId);
            return null;
        }

        MesInventoryQueryResult queryResult = queryInventoryFromMes(inventoryId);
        if (Objects.isNull(queryResult)) {
            return null;
        }
        U8InventoryAddParam u8InventoryAddParam = queryResult.buildU8InventoryAddParamByMes();
        U8CommonSyncResponse commonSyncResult = addInventoryOfU8(u8InventoryAddParam);

        return commonSyncResult;

        // if(Objects.nonNull(commonSyncResult) && CommonValue.U8_RESPONSE_SUCCESS.equals(u8AddSyncResult.getErrcode())) {
        //     log.info("InventoryAppService addInventoryOfU8IfNotExist add success : [{}]", inventoryId);
        //     return true;
        // }
        //
        // log.error("InventoryAppService addInventoryOfU8IfNotExist add failed : [{}] -- {}", inventoryId, Objects.nonNull(u8AddSyncResult) ? "null" : (u8AddSyncResult.getErrcode() + "-" + u8AddSyncResult.getErrmsg()));
        // return false;
    }

}
